﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;

namespace Nirvana
{
    [Serializable]

    public sealed class CheckUI
    {

		private enum CanvasPixelPerfectMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Force On")]
			ForceOn,
			[EnumLabel("Force Off")]
			ForceOff
		}
		[EnumLabel]
		[SerializeField]
		[Tooltip("The canvas pixel perfect check mode.")]
		private CanvasPixelPerfectMode canvasPixelPerfectMode;

		private enum CanvasScreenMatchMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Force MatchWidthOrHeight")]
			MatchWidthOrHeight,
			[EnumLabel("Force Expand")]
			Expand,
			[EnumLabel("Force Shrink")]
			Shrink
		}
		[EnumLabel]
		[Tooltip("The canvas screen match check mode.")]
		[SerializeField]
		private CanvasScreenMatchMode canvasScreenMatchMode;

		[SerializeField]
		[EnumMask]
		[Tooltip("The canvas shader channels must have.")]
		private AdditionalCanvasShaderChannels mustHaveCanvasShaderChannels;
		[EnumMask]
		[Tooltip("The canvas shader channels can not have.")]
		[SerializeField]
		private AdditionalCanvasShaderChannels canNotHaveCanvasShaderChannels;


		private enum CanvasScaleMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Force ConstantPixelSize")]
			ConstantPixelSize,
			[EnumLabel("Force ScaleWithScreenSize")]
			ScaleWithScreenSize,
			[EnumLabel("Force ConstantPhysicalSize")]
			ConstantPhysicalSize
		}

		[SerializeField]
		[Tooltip("The canvas scale check mode.")]
		[EnumLabel]
		private CanvasScaleMode canvasScaleMode;
		[Tooltip("The reference resolution check.")]
		[SerializeField]
		private Vector2 referenceResolution;


		private enum EmptyCanvasRendererMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Check")]
			Check
		}
		[EnumLabel]
		[Tooltip("The empty canvas renderer check mode.")]
		[SerializeField]
		private EmptyCanvasRendererMode emptyCanvasRendererMode;

		private enum TextNoneFontMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Check")]
			Check
		}
		[SerializeField]
		[Tooltip("The none font check mode.")]
		[EnumLabel]
		private TextNoneFontMode textNoneFontMode;

		private enum TextBestFitMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Force Best Fit")]
			BestFit,
			[EnumLabel("Force Not")]
			ForceNot
		}
		[SerializeField]
		[Tooltip("The best fit check mode.")]
		[EnumLabel]
		private TextBestFitMode textBestFitMode;
		[Tooltip("The valid font size for check.")]
		[SerializeField]
		private int[] textFontSizes;

		private enum VariableBindMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("No Empty Bind")]
			NoEmptyBind
		}
		[EnumLabel]
		[SerializeField]
		[Tooltip("The variable bind check mode.")]
		private VariableBindMode variableBindMode;


		private enum VariableMissingMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("No Missing")]
			NoMissing
		}
		[SerializeField]
		[Tooltip("The variable missing check mode.")]
		[EnumLabel]
		private VariableMissingMode variableMissingMode;

		private enum RaycastTargetMode
		{
			[EnumLabel("Not Check")]
			NotCheck,
			[EnumLabel("Force Off")]
			ForceOff
		}
		[SerializeField]
		[Tooltip("The raycast target mode.")]
		[EnumLabel]
		private RaycastTargetMode raycastTargetMode;

		[Tooltip("Check the position z whether is 0.")]
		[SerializeField]
		private bool checkPosZ0;

		[SerializeField]
		[Tooltip("Check the invisible scroll bar.")]
		private bool checkInvisibleScrollBar;


		public void checkPosZtoZero(AssetCheckReport report, RectTransform rectrans)
		{
			if (this.checkPosZ0 && !Mathf.Approximately(rectrans.anchoredPosition3D.z, 0f))
			{
				report.ShowWarnInfo("The RectTransform <b><color=orange>{0}</color></b>' position Z is not 0.", rectrans.name);
			}
		}

		public void CheckCanvas(AssetCheckReport report, Canvas canvas)
		{
			if (this.canvasPixelPerfectMode == CanvasPixelPerfectMode.ForceOn)
			{
				if (!canvas.pixelPerfect)
				{
					report.ShowWarnInfo("The Canvas <b><color=orange>{0}</color></b>' does not turn on the pixel perfect.", canvas.name);
				}
			}
			else if (this.canvasPixelPerfectMode == CanvasPixelPerfectMode.ForceOff && canvas.pixelPerfect)
			{
				report.ShowWarnInfo("The Canvas <b><color=orange>{0}</color></b>' can not turn on the pixel perfect.", canvas.name);
			}
			if ((canvas.additionalShaderChannels & this.canNotHaveCanvasShaderChannels) != AdditionalCanvasShaderChannels.None)
			{
				report.ShowWarnInfo("The Canvas <b><color=orange>{0}</color></b>' contain invalid shader channels.", canvas.name);
			}
			if (this.mustHaveCanvasShaderChannels != AdditionalCanvasShaderChannels.None && (canvas.additionalShaderChannels & this.mustHaveCanvasShaderChannels) == AdditionalCanvasShaderChannels.None)
			{
				report.ShowWarnInfo("The Canvas <b><color=orange>{0}</color></b>' does not contain necessary shader channels.", canvas.name);
			}
		}

		public void CheckCanvasScaler(AssetCheckReport report, CanvasScaler  canvasScaler)
		{
			if (this.canvasScreenMatchMode == CanvasScreenMatchMode.MatchWidthOrHeight)
			{
				if (canvasScaler.screenMatchMode != CanvasScaler.ScreenMatchMode.MatchWidthOrHeight)
				{
					report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s screenMatchMode is not MatchWidthOrHeight.", canvasScaler.name);
				}
			}
			else if (this.canvasScreenMatchMode == CanvasScreenMatchMode.Expand)
			{
				if (canvasScaler.screenMatchMode != CanvasScaler.ScreenMatchMode.Expand)
				{
					report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s screenMatchMode is not Expand.", canvasScaler.name);
				}
			}
			else if (this.canvasScreenMatchMode == CanvasScreenMatchMode.Shrink && canvasScaler.screenMatchMode != CanvasScaler.ScreenMatchMode.Shrink)
			{
				report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s screenMatchMode is not Shrink.", canvasScaler.name);
			}
			if (this.canvasScaleMode == CanvasScaleMode.ConstantPixelSize)
			{
				if (canvasScaler.uiScaleMode !=  CanvasScaler.ScaleMode.ConstantPixelSize)
				{
					report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s uiScaleMode is not ConstantPixelSize.", canvasScaler.name);
				}
			}
			else if (this.canvasScaleMode == CanvasScaleMode.ScaleWithScreenSize)
			{
				if (canvasScaler.uiScaleMode != CanvasScaler.ScaleMode.ScaleWithScreenSize)
				{
					report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s uiScaleMode is not ScaleWithScreenSize.", canvasScaler.name);
				}
			}
			else if (this.canvasScaleMode == CanvasScaleMode.ConstantPhysicalSize && canvasScaler.uiScaleMode != CanvasScaler.ScaleMode.ConstantPhysicalSize)
			{
				report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s uiScaleMode is not ConstantPhysicalSize.", canvasScaler.name);
			}
			if ((this.referenceResolution.x >= 1f || this.referenceResolution.y >= 1f) && this.referenceResolution != canvasScaler.referenceResolution)
			{
				report.ShowWarnInfo("The CanvasScaler <b><color=orange>{0}</color></b>'s referenceResolution is not <b><color=orange>{1}</color></b>.", canvasScaler.name, this.referenceResolution);
			}
		}

		public void CheckEmptyCanvasRenderer(AssetCheckReport report, CanvasRenderer  canvasRenderer)
		{
			if (this.emptyCanvasRendererMode == EmptyCanvasRendererMode.Check)
			{
				Graphic component = canvasRenderer.GetComponent<Graphic>();
				if (component == null)
				{
					report.ShowWarnInfo("The CanvasRenderer <b><color=orange>{0}</color></b> has no attached Graphic.", canvasRenderer.name);
				}
			}
		}

		public void CheckMaskableGraphic(AssetCheckReport report, MaskableGraphic mask)
		{
			if (this.raycastTargetMode == RaycastTargetMode.ForceOff && mask.raycastTarget)
			{
				report.ShowWarnInfo("The MaskableGraphic <b><color=orange>{0}</color></b> can not turn on the raycastTarget.", mask.name);
			}
		}

		public void CheckText(AssetCheckReport report, Text text)
		{
			if (this.textNoneFontMode == TextNoneFontMode.Check && text.font == null)
			{
				report.ShowWarnInfo("The Text <b><color=orange>{0}</color></b> has no font.", text.name);
			}
			if (this.textBestFitMode == TextBestFitMode.BestFit)
			{
				if (!text.resizeTextForBestFit)
				{
					report.ShowWarnInfo("The Text <b><color=orange>{0}</color></b> is not best fit, but it required to.", text.name);
				}
			}
			else if (this.textBestFitMode == TextBestFitMode.ForceNot && text.resizeTextForBestFit)
			{
				report.ShowWarnInfo("The Text <b><color=orange>{0}</color></b> is best fit, but it required not to.", text.name);
			}
			if (this.textFontSizes != null && this.textFontSizes.Length > 0)
			{
				Font font = text.font;
				if (font.dynamic && Array.IndexOf<int>(this.textFontSizes, text.fontSize) < 0)
				{
					report.ShowWarnInfo("The Text <b><color=orange>{0}</color></b> has font size <b><color=orange>{1}</color></b> is invalid.", text.name,text.fontSize);
				}
			}
		}

		public void CheckScrollRect(AssetCheckReport report, ScrollRect sr)
		{
			if (this.checkInvisibleScrollBar)
			{
				Scrollbar horizontalScrollbar = sr.horizontalScrollbar;
				if (horizontalScrollbar != null)
				{
					Graphic[] componentsInChildren = horizontalScrollbar.GetComponentsInChildren<Graphic>();
					if (componentsInChildren.Length == 0)
					{
						report.ShowWarnInfo("The scroll rect has an invisible horizontal scrollbar.");
					}
				}
				Scrollbar verticalScrollbar = sr.verticalScrollbar;
				if (verticalScrollbar != null)
				{
					Graphic[] componentsInChildren2 = verticalScrollbar.GetComponentsInChildren<Graphic>();
					if (componentsInChildren2.Length == 0)
					{
						report.ShowWarnInfo("The scroll rect has an invisible vertical scrollbar.");
					}
				}
			}
		}

		public void CheckUIVariableTable(AssetCheckReport report, UIVariableTable uitable)
		{
			if (this.variableBindMode == VariableBindMode.NoEmptyBind)
			{
				uitable.InitializeBinds();
				foreach (UIVariable uivariable in uitable.Variables)
				{
					bool flag = false;
					foreach (UIVariableBind x in uivariable.UIVariableBindList)
					{
						if (x != null)
						{
							flag = true;
							break;
						}
					}
					if (!flag)
					{
						report.ShowWarnInfo("The Variable Table <b><color=orange>{0}</color></b> has a variable <b><color=orange>{1}</color></b> without any bind.",uitable.name, uivariable.VariableName);
					}
				}
			}
		}

	}
}
